package com.async.config;

import com.async.handler.AsyncHandlerService;
import com.async.handler.AsyncStrategyFactory;
import com.async.handler.context.AsyncStrategyContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.util.Assert;

/**
 * <p>
 * 异步监听器
 * </p>
 * @author yang
 * @date 2024/5/17
 */
@Slf4j
@Component
public class AsyncListener {

    /**
     * 处理事件 <br>
     * fallbackExecution=true 没有事务正在运行，依然处理事件 <br>
     * TransactionPhase.AFTER_COMPLETION 事务提交，事务回滚都处理事件
     * Retryable Spring 会重新执行该方法直至成功，最多重试 3 次，可设置间隔时间，重试间隔递增时间。
     * @param context
     */
    @TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMPLETION)
    @Retryable(value = Exception.class, maxAttempts = 4, backoff = @Backoff(delay = 100L, multiplier = 2))
    public void asyncHandler(AsyncStrategyContext context) {
        AsyncHandlerService handlerService = AsyncStrategyFactory.doStrategy(context.getAsyncExec().type().name(), AsyncHandlerService.class);
        Assert.notNull(handlerService, "异步执行策略不存在");
        handlerService.handle(context);
    }

}
